package com.datagateway.controller;

import com.datagateway.component.DataCompressionManager;
import com.datagateway.component.DataSerializationManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 数据优化控制器
 * 提供数据压缩和序列化优化的API接口
 * 
 * @author Data Gateway Team
 * @version 1.0.0
 */
@RestController
@RequestMapping("/api/optimization")
public class DataOptimizationController {

    @Autowired
    private DataCompressionManager compressionManager;

    @Autowired
    private DataSerializationManager serializationManager;

    /**
     * 获取压缩统计信息
     * 
     * @return 压缩统计信息
     */
    @GetMapping("/compression/statistics")
    public Map<String, Object> getCompressionStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            DataCompressionManager.CompressionStatistics statistics = compressionManager.getStatistics();
            
            result.put("success", true);
            result.put("statistics", statistics);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取压缩统计信息失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取序列化统计信息
     * 
     * @return 序列化统计信息
     */
    @GetMapping("/serialization/statistics")
    public Map<String, Object> getSerializationStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            DataSerializationManager.SerializationStatistics statistics = serializationManager.getStatistics();
            
            result.put("success", true);
            result.put("statistics", statistics);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取序列化统计信息失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 设置默认压缩算法
     * 
     * @param request 压缩算法设置请求
     * @return 操作结果
     */
    @PostMapping("/compression/algorithm")
    public Map<String, Object> setCompressionAlgorithm(@RequestBody CompressionAlgorithmRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            DataCompressionManager.CompressionAlgorithm algorithm = 
                DataCompressionManager.CompressionAlgorithm.valueOf(request.getAlgorithm().toUpperCase());
            
            compressionManager.setDefaultAlgorithm(algorithm);
            
            result.put("success", true);
            result.put("algorithm", algorithm.getName());
            result.put("message", "默认压缩算法已更新: " + algorithm.getName());
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "设置压缩算法失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 设置默认序列化格式
     * 
     * @param request 序列化格式设置请求
     * @return 操作结果
     */
    @PostMapping("/serialization/format")
    public Map<String, Object> setSerializationFormat(@RequestBody SerializationFormatRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            DataSerializationManager.SerializationFormat format = 
                DataSerializationManager.SerializationFormat.valueOf(request.getFormat().toUpperCase());
            
            serializationManager.setDefaultFormat(format);
            
            result.put("success", true);
            result.put("format", format.getName());
            result.put("message", "默认序列化格式已更新: " + format.getName());
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "设置序列化格式失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 压缩数据
     * 
     * @param request 压缩请求
     * @return 压缩结果
     */
    @PostMapping("/compression/compress")
    public Map<String, Object> compressData(@RequestBody CompressionRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            byte[] data = request.getData().getBytes("UTF-8");
            DataCompressionManager.CompressionAlgorithm algorithm = 
                DataCompressionManager.CompressionAlgorithm.valueOf(request.getAlgorithm().toUpperCase());
            
            byte[] compressedData = compressionManager.compress(data, algorithm);
            
            result.put("success", true);
            result.put("originalSize", data.length);
            result.put("compressedSize", compressedData.length);
            result.put("compressionRatio", (double) compressedData.length / data.length);
            result.put("compressedData", java.util.Base64.getEncoder().encodeToString(compressedData));
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "数据压缩失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 解压数据
     * 
     * @param request 解压请求
     * @return 解压结果
     */
    @PostMapping("/compression/decompress")
    public Map<String, Object> decompressData(@RequestBody DecompressionRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            byte[] compressedData = java.util.Base64.getDecoder().decode(request.getCompressedData());
            DataCompressionManager.CompressionAlgorithm algorithm = 
                DataCompressionManager.CompressionAlgorithm.valueOf(request.getAlgorithm().toUpperCase());
            
            byte[] decompressedData = compressionManager.decompress(compressedData, algorithm);
            
            result.put("success", true);
            result.put("compressedSize", compressedData.length);
            result.put("decompressedSize", decompressedData.length);
            result.put("decompressedData", new String(decompressedData, "UTF-8"));
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "数据解压失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 序列化对象
     * 
     * @param request 序列化请求
     * @return 序列化结果
     */
    @PostMapping("/serialization/serialize")
    public Map<String, Object> serializeObject(@RequestBody SerializationRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Object object = request.getObject();
            DataSerializationManager.SerializationFormat format = 
                DataSerializationManager.SerializationFormat.valueOf(request.getFormat().toUpperCase());
            
            byte[] serializedData = serializationManager.serialize(object, format);
            
            result.put("success", true);
            result.put("objectType", object.getClass().getSimpleName());
            result.put("serializedSize", serializedData.length);
            result.put("serializedData", java.util.Base64.getEncoder().encodeToString(serializedData));
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "对象序列化失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 反序列化对象
     * 
     * @param request 反序列化请求
     * @return 反序列化结果
     */
    @PostMapping("/serialization/deserialize")
    public Map<String, Object> deserializeObject(@RequestBody DeserializationRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            byte[] serializedData = java.util.Base64.getDecoder().decode(request.getSerializedData());
            DataSerializationManager.SerializationFormat format = 
                DataSerializationManager.SerializationFormat.valueOf(request.getFormat().toUpperCase());
            
            Object deserializedObject = serializationManager.deserialize(serializedData, Object.class, format);
            
            result.put("success", true);
            result.put("serializedSize", serializedData.length);
            result.put("deserializedObject", deserializedObject);
            result.put("objectType", deserializedObject.getClass().getSimpleName());
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "对象反序列化失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取支持的压缩算法
     * 
     * @return 支持的压缩算法列表
     */
    @GetMapping("/compression/algorithms")
    public Map<String, Object> getSupportedCompressionAlgorithms() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            DataCompressionManager.CompressionAlgorithm[] algorithms = 
                DataCompressionManager.CompressionAlgorithm.values();
            
            String[] algorithmNames = new String[algorithms.length];
            for (int i = 0; i < algorithms.length; i++) {
                algorithmNames[i] = algorithms[i].getName();
            }
            
            result.put("success", true);
            result.put("algorithms", algorithmNames);
            result.put("defaultAlgorithm", compressionManager.getDefaultAlgorithm().getName());
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取支持的压缩算法失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取支持的序列化格式
     * 
     * @return 支持的序列化格式列表
     */
    @GetMapping("/serialization/formats")
    public Map<String, Object> getSupportedSerializationFormats() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            DataSerializationManager.SerializationFormat[] formats = 
                DataSerializationManager.SerializationFormat.values();
            
            String[] formatNames = new String[formats.length];
            for (int i = 0; i < formats.length; i++) {
                formatNames[i] = formats[i].getName();
            }
            
            result.put("success", true);
            result.put("formats", formatNames);
            result.put("defaultFormat", serializationManager.getDefaultFormat().getName());
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取支持的序列化格式失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 重置压缩统计信息
     * 
     * @return 操作结果
     */
    @PostMapping("/compression/reset-statistics")
    public Map<String, Object> resetCompressionStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            compressionManager.resetStatistics();
            
            result.put("success", true);
            result.put("message", "压缩统计信息已重置");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "重置压缩统计信息失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 重置序列化统计信息
     * 
     * @return 操作结果
     */
    @PostMapping("/serialization/reset-statistics")
    public Map<String, Object> resetSerializationStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            serializationManager.resetStatistics();
            
            result.put("success", true);
            result.put("message", "序列化统计信息已重置");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "重置序列化统计信息失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 压缩算法设置请求类
     */
    public static class CompressionAlgorithmRequest {
        private String algorithm;

        // Getter和Setter方法
        public String getAlgorithm() { return algorithm; }
        public void setAlgorithm(String algorithm) { this.algorithm = algorithm; }
    }

    /**
     * 序列化格式设置请求类
     */
    public static class SerializationFormatRequest {
        private String format;

        // Getter和Setter方法
        public String getFormat() { return format; }
        public void setFormat(String format) { this.format = format; }
    }

    /**
     * 压缩请求类
     */
    public static class CompressionRequest {
        private String data;
        private String algorithm;

        // Getter和Setter方法
        public String getData() { return data; }
        public void setData(String data) { this.data = data; }
        
        public String getAlgorithm() { return algorithm; }
        public void setAlgorithm(String algorithm) { this.algorithm = algorithm; }
    }

    /**
     * 解压请求类
     */
    public static class DecompressionRequest {
        private String compressedData;
        private String algorithm;

        // Getter和Setter方法
        public String getCompressedData() { return compressedData; }
        public void setCompressedData(String compressedData) { this.compressedData = compressedData; }
        
        public String getAlgorithm() { return algorithm; }
        public void setAlgorithm(String algorithm) { this.algorithm = algorithm; }
    }

    /**
     * 序列化请求类
     */
    public static class SerializationRequest {
        private Object object;
        private String format;

        // Getter和Setter方法
        public Object getObject() { return object; }
        public void setObject(Object object) { this.object = object; }
        
        public String getFormat() { return format; }
        public void setFormat(String format) { this.format = format; }
    }

    /**
     * 反序列化请求类
     */
    public static class DeserializationRequest {
        private String serializedData;
        private String format;

        // Getter和Setter方法
        public String getSerializedData() { return serializedData; }
        public void setSerializedData(String serializedData) { this.serializedData = serializedData; }
        
        public String getFormat() { return format; }
        public void setFormat(String format) { this.format = format; }
    }
}
